<?php
/**
 * 短信验证码服务 -- easySms
 * zhouliang
 * 2020.08.29
 */

namespace App\Services\Tools;

use Carbon\Carbon;
use Overtrue\EasySms\EasySms;
use App\Exceptions\BasicException;
use Illuminate\Support\Facades\Log;
use Overtrue\EasySms\Exceptions\Exception;

class EasySmsService {
    private static $_error_msg = '';
    private static $_error_code = '';
    
    
    /**
     * @param $mobile string 手机号码
     * @param $type string 1注册 2找回密码 3验证旧手机 4.绑定新手机 5.设置二级密码 6.绑定银行卡 7.找回qq账号 8.注销账号 9.快捷认证(支付宝身份验证) 10.人工认证
     * @param array $param 参数
     * @param int $limit 单位:分钟
     * @return string
     * @throws BasicException
     * @throws \Overtrue\EasySms\Exceptions\InvalidArgumentException
     * @throws \Overtrue\EasySms\Exceptions\NoGatewayAvailableException
     */
    public static function send($mobile, $type, $param = [], $limit = 1,$template_id="") {
        $key = 'sms:' . $mobile . ':' . $type;
        if ($limit > 0 && app('redis')->get($key)) {
            throw new BasicException(0, $limit . '分钟可获取一次');
        }
        $config = config('sms');
        $easySms = new EasySms($config);
        $sms_code = isset($param['code'])?$param['code']:mt_rand(1000, 9999);
        switch ($type) {
            case 1: //注册
                if(empty($template_id)){
                    $template_id = 'SMS_179855152';
                }else{
                    $template_id = 'SMS_179855154';
                }
                break;
            case 2: //找回密码
                $template_id = 'SMS_179855151';
                break;
            case 8: //注销账号
                $template_id = 'SMS_193237063';
                break;
            default:
                $template_id = 'SMS_179855150';
                break;
        }
        $param['code'] = $sms_code;

        if (env('SMS_REAL_SEND')) {
            try {
                $easySms->send($mobile, [
                    'template' => $template_id,
                    'data'     => $param,
                ]);
            } catch (Exception $exception) {
                $error_msg = $exception->getException('aliyun')->getMessage() ?? '发送失败，请重试';
                Log::error($error_msg);
                throw new BasicException(0, $error_msg);
            }
        }

        app('model_sms_history')->create([
            'mobile'   => $mobile,
            'code'     => $sms_code,
            'add_time' => Carbon::now()->timestamp,
            'type'     => $type
        ]);

        app('redis')->setex($key, $limit*60, $sms_code);
        return true;
    }

    public static function sendThreeWarningMsg($url, $phone, $type){
            return false;
    }

    //给风控管理员发预警短信
    public static function sentryToAdmin($code)
    {
        $config = config('sms');
        $easySms = new EasySms($config);

        if (env('SMS_REAL_SEND')) {
            try {
                $easySms->send('13591582110', [
                    'template' => 'SMS_179855150',
                    'data'     => [
                        'code' => $code
                    ],
                ]);
                $easySms->send('13552732093', [
                    'template' => 'SMS_179855150',
                    'data'     => [
                        'code' => $code
                    ],
                ]);
                $easySms->send('18268125439', [
                    'template' => 'SMS_179855150',
                    'data'     => [
                        'code' => $code
                    ],
                ]);
            } catch (Exception $exception) {
                $error_msg = $exception->getException('aliyun')->getMessage() ?? '发送失败，请重试';
                Log::error($error_msg);
                throw new BasicException(0, $error_msg);
            }
        }

    }


    //用户账务异常风控报警
    public static function sentryToAdminByAccount($code)
    {
        $config = config('sms');
        $easySms = new EasySms($config);

        if (env('SMS_REAL_SEND')) {
            try {
                $easySms->send('13591582110', [
                    'template' => 'SMS_179855155',
                    'data'     => [
                        'code' => $code
                    ],
                ]);
                $easySms->send('13552732093', [
                    'template' => 'SMS_179855155',
                    'data'     => [
                        'code' => $code
                    ],
                ]);
            } catch (Exception $exception) {
                $error_msg = $exception->getException('aliyun')->getMessage() ?? '发送失败，请重试';
                Log::error($error_msg);
                throw new BasicException(0, $error_msg);
            }
        }

    }

    public static function verify($mobile, $code, $type) {
        $where = [
            'mobile' => $mobile,
            'type' => $type,
            'status' => 0,
        ];
        $data = app('model_sms_history')->where($where)->orderBy('id', 'desc')->first();
        $result = false;
        $key = 'u:login_error_times:'.$mobile.':'.$type;
    
        if (isset($data) && $data->status == 0 && $data->code == $code) {
            if ($data->add_time < (Carbon::now()->timestamp - 1800)) {
                $status = 2;
                $result = false;
                self::$_error_msg = '验证码已过期';
            } else {
                $status = 1;
                $result = true;
            }
            app('model_sms_history')->where(['id' => $data->id, 'status' => 0])->update([
                'status'      => $status,
                'update_time' => Carbon::now()->timestamp
            ]);
        
        }
        //记录错误次数
        if(!$result){
            self::$_error_msg = '验证码错误';
            $times = app('redis')->incr($key);
            if ($times >= 5) {
                app('model_sms_history')->where($where)->update([
                    'status'      => 2,
                    'update_time' => Carbon::now()->timestamp
                ]);
                self::$_error_msg = '验证码输入错误次数过多，已失效，请重新获取';
                app('redis')->del($key);
                return false;
            } elseif ($times == 1) {
                app('redis')->expire($key,strtotime(date('Ymd')) + 86400 - time());
            }
        }
        return $result;
    }
    
    public static function getErrorMsg(){
        return [
            'error_code' => 0,
            'error_msg' => self::$_error_msg?self::$_error_msg:'验证码错误!',
        ];
    }
}
